package com.mengxinya.ys.social.wechatplatform.impl;

import com.mengxinya.ys.social.wechatplatform.*;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpMessageRouterRule;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.stereotype.Service;

import jakarta.servlet.ServletInputStream;
import java.util.List;

@Service
@Slf4j
public class WechatPlatformServiceImpl implements WechatPlatformService {
    private final WxMpService wxService;
    private final WxMpMessageRouter wxMpMessageRouter;
    private final WxMpConfigStorage wxMpConfigStorage;

    public WechatPlatformServiceImpl(MpConfig mpConfig, WechatPlatformHandlerProvider handlerProvider) {
        WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
        config.setAppId(mpConfig.getAppId()); // 设置微信公众号的appid
        config.setSecret(mpConfig.getSecret()); // 设置微信公众号的app corpSecret
        config.setToken(mpConfig.getToken()); // 设置微信公众号的token
        config.setAesKey(mpConfig.getAesKey()); // 设置微信公众号的EncodingAESKey

        wxMpConfigStorage = config;

        wxService = new WxMpServiceImpl();
        wxService.setWxMpConfigStorage(config);
        wxMpMessageRouter = new WxMpMessageRouter(wxService);

        handlerProvider.getHandlers().forEach(handler -> {
            WxMpMessageRouterRule rule = wxMpMessageRouter.rule();
            rule.async(false);
            if (handler.rule().getMsgType() != null) {
                rule = rule.msgType(handler.rule().getMsgType());
            }
            if (handler.rule().getEvent() != null) {
                rule = rule.event(handler.rule().getEvent());
            }
            if (handler.rule().getEventKey() != null) {
                rule = rule.eventKey(handler.rule().getEventKey());
            }
            if (handler.rule().getContent() != null) {
                rule = rule.content(handler.rule().getContent());
            }

            rule.handler((wxMessage, context, wxMpService, sessionManager) -> {
                WechatMpMessage message = new WechatMpMessage();
                message.setFromUser(wxMessage.getFromUser());
                message.setToUser(wxMessage.getToUser());
                message.setCreateTime(wxMessage.getCreateTime());
                message.setMsgType(wxMessage.getMsgType());
                message.setContent(wxMessage.getContent());
                message.setPicUrl(wxMessage.getPicUrl());

                WechatMpReplyMessage replyMessage = handler.handle(message);

                if (replyMessage.messageType().equals(WechatMpReplyMessageType.TEXT)) {
                    log.info("reply text message");
                    WechatMpTextReplyMessage textMessage = (WechatMpTextReplyMessage) replyMessage;
                    return WxMpXmlOutMessage.TEXT().content(textMessage.getContent()).fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).build();
                } else if (replyMessage.messageType().equals(WechatMpReplyMessageType.IMAGE)) {
                    WechatMpImageReplyMessage imageMessage = (WechatMpImageReplyMessage) replyMessage;
                    return WxMpXmlOutMessage.IMAGE().mediaId(imageMessage.getMediaId()).fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).build();
                } else if (replyMessage.messageType().equals(WechatMpReplyMessageType.VOICE)) {
                    WechatMpVoiceReplyMessage voiceMessage = (WechatMpVoiceReplyMessage) replyMessage;
                    return WxMpXmlOutMessage.VOICE().mediaId(voiceMessage.getMediaId()).fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).build();
                } else if (replyMessage.messageType().equals(WechatMpReplyMessageType.VIDEO)) {
                    WechatMpVideoReplyMessage videoMessage = (WechatMpVideoReplyMessage) replyMessage;
                    return WxMpXmlOutMessage.VIDEO().mediaId(videoMessage.getMediaId()).title(videoMessage.getTitle()).description(videoMessage.getDescription()).fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).build();
                } else if (replyMessage.messageType().equals(WechatMpReplyMessageType.MUSIC)) {
                    WechatMpMusicReplyMessage musicMessage = (WechatMpMusicReplyMessage) replyMessage;
                    return WxMpXmlOutMessage.MUSIC().title(musicMessage.getTitle()).description(musicMessage.getDescription()).musicUrl(musicMessage.getMusicUrl()).hqMusicUrl(musicMessage.getHqMusicUrl()).thumbMediaId(musicMessage.getThumbMediaId()).fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).build();
                } else if (replyMessage.messageType().equals(WechatMpReplyMessageType.NEWS)) {
                    WechatMpNewsReplyMessage newsMessage = (WechatMpNewsReplyMessage) replyMessage;

                    var builder = WxMpXmlOutMessage.NEWS().fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser());
                    newsMessage.getArticles().forEach(article -> {
                        WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item();
                        item.setDescription(article.getDescription());
                        item.setPicUrl(article.getPicUrl());
                        item.setTitle(article.getTitle());
                        item.setUrl(article.getUrl());
                        builder.addArticle(item);
                    });
                    return builder.build();
                } else {
                    return WxMpXmlOutMessage.TEXT().content("服务器错误").fromUser(wxMessage.getToUser()).toUser(wxMessage.getFromUser()).build();
                }
            });

            rule.end();

        });
    }

    @Override
    public boolean checkSignature(WechatConnectVo vo) {
        return wxService.checkSignature(vo.timestamp(), vo.nonce(), vo.signature());
    }

    @Override
    public String service(ServletInputStream inputStream, List<WechatPlatformHandler> handlers, String timestamp, String nonce, String msgSignature) {
        log.info("接收到微信消息");
        WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(inputStream, wxMpConfigStorage, timestamp, nonce, msgSignature);
        WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
        if(outMessage == null) {
            log.info("未匹配到消息处理器");
            return "";
        }
        log.info("返回消息");
        return outMessage.toEncryptedXml(wxMpConfigStorage);
    }

}
